package com.example.demo.sm;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

/**
 * SM2\SM3\SM4加密解密工具类
 *
 * @author yz
 * @date 2023-11-07
 */
@Slf4j
public class SmEncryptionUtil {

    /**
     * 根据公钥私钥初始化SM2对象
     */
    private static SM2 sm2 = SmUtil.sm2(SmEncryptionConstants.SM2_PRIVATE_KEY, SmEncryptionConstants.SM2_PUBLIC_KEY);
    /**
     * 根据密钥初始化SM4对象
     */
    private static SymmetricCrypto sm4 = SmUtil.sm4(SmEncryptionConstants.SM4_SECRET_KEY);

    /**
     * 获取SM2的私钥
     *
     * @return 私钥字符串
     */
    public static String getSm2PrivateKey() {
        return SmEncryptionConstants.SM2_PRIVATE_KEY;
    }

    /**
     * 获取SM2的公钥
     *
     * @return 公钥字符串
     */
    public static String getSm2PublicKey() {
        return SmEncryptionConstants.SM2_PUBLIC_KEY;
    }

    /**
     * 获取SM4的密钥
     *
     * @return 密钥
     */
    public static byte[] getSm4SecretKey() {
        return SmEncryptionConstants.SM4_SECRET_KEY;
    }

    /**
     * SM2加密
     *
     * @param dataStr 数据字符串
     * @return 加密后的字符串
     */
    public static String sm2Encrypt(String dataStr) {
        try {
            if (StringUtils.isNotBlank(dataStr)) {
                return sm2.encryptBcd(dataStr, KeyType.PublicKey);
            } else {
                log.error("EncryptionUtil.sm2Encrypt dataStr is Blank!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("EncryptionUtil.sm2Encrypt failed:{}", e.getMessage());
        }
        return null;
    }

    /**
     * SM2解密
     *
     * @param dataStr 数据字符串
     * @return 解密后的字符串
     */
    public static String sm2Decrypt(String dataStr) {
        try {
            if (StringUtils.isNotBlank(dataStr)) {
                byte[] bytes = sm2.decryptFromBcd(dataStr, KeyType.PrivateKey);
                return StrUtil.utf8Str(bytes);
            } else {
                log.error("EncryptionUtil.sm2Decrypt dataStr is Blank!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("EncryptionUtil.sm2Decrypt failed:{}", e.getMessage());
        }
        return null;
    }

    /**
     * SM3摘要加密
     *
     * @param dataStr 数据字符串
     * @return 摘要字符串
     */
    public static String sm3DigestHex(String dataStr) {
        try {
            if (StringUtils.isNotBlank(dataStr)) {
                return SmUtil.sm3(dataStr);
            } else {
                log.error("EncryptionUtil.sm3DigestHex dataStr is Blank!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("EncryptionUtil.sm3DigestHex failed:{}", e.getMessage());
        }
        return null;
    }

    /**
     * SM4加密
     *
     * @param dataStr 数据字符串
     * @return 加密后的字符串
     */
    public static String sm4Encrypt(String dataStr) {
        try {
            if (StringUtils.isNotBlank(dataStr)) {
                return sm4.encryptHex(dataStr);
            } else {
                log.error("EncryptionUtil.sm4Encrypt dataStr is Blank!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("EncryptionUtil.sm4Encrypt failed:{}", e.getMessage());
        }
        return null;
    }

    /**
     * SM4解密
     *
     * @param dataStr 数据字符串
     * @return 解密后的字符串
     */
    public static String sm4Decrypt(String dataStr) {
        try {
            if (StringUtils.isNotBlank(dataStr)) {
                return sm4.decryptStr(dataStr, CharsetUtil.CHARSET_UTF_8);
            } else {
                log.error("EncryptionUtil.sm4Decrypt dataStr is Blank!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("EncryptionUtil.sm4Decrypt failed:{}", e.getMessage());
        }
        return null;
    }


}
